#include "common/common.h"

struct my_file{
    char name[50];
    uint64_t size;
    char buff[4096];
};

const int MAXLINE = 1024;

//接受数据
int recv_packet(int confd, char* buff, int size){
    int cur = 0;
    char* ptr = buff;
    
    int data = 0;
    while(cur < size){
        int count = 0;
        if(size - cur < MAXLINE){
            data = size -cur;
        }else{
            data = MAXLINE;
        }

        if((count = recv(confd, ptr, data, 0)) <= 0){
            perror("recv");
            return -1;
        }
        cur += count;
        ptr += count;
    }
    DBG(GREEN"should recv %d, actually recv %d\n"NONE, size, cur);
    return 0;
}

//抽取数据
void extract_data(char* buff){
    struct my_file* temp = (struct my_file*)buff;
    FILE *fp = fopen(temp->name, "a+");
    int fd = fileno(fp);
    uint64_t pos = lseek(fd, 0, SEEK_END);
    uint64_t count = 0;
    DBG(BLUE"cur file size : %lu\n"NONE, pos);
    DBG(BLUE"size is %lu\n"NONE, temp->size);
    if(temp->size - pos < 4096){
        count = temp->size - pos;
    }else{
        count = 4096;
    }
    ssize_t num = fwrite(temp->buff, count, 1, fp);
    DBG(BLUE"should write %ld, actually write %lu\n", count, num);
    return;
}


int main(int argc, char** argv){
    int opt;
    int port;
    if(argc != 3){
        fprintf(stderr, "Usage : %s -p port\n", argv[0]);
        exit(1);
    }
    while((opt = getopt(argc, argv, "p:")) != -1){
        switch(opt){
            case 'p':
                port = atoi(optarg);
                break;
            default:
                fprintf(stderr, "Usage : %s -p port\n", argv[0]);
                exit(1);
        }
    }

    int listenfd = server_init(port);
    if(listenfd < 0){
        perror("server_init");
        exit(1);
    }
    DBG(BLUE"listening...\n"NONE);

    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    bzero(&client, sizeof(client));
    int confd = accept(listenfd, (struct sockaddr*)&client, &len);
    if(confd < 0){
        perror("accept");
        exit(1);
    }
    char ip[30] = {0};
    DBG(BLUE"accept from client %s in port %d\n"NONE,inet_ntop(AF_INET, &client.sin_addr, ip, sizeof(ip)), ntohs(client.sin_port));
    DBG(BLUE"accept success\n"NONE);
    DBG(BLUE"confd is %d\n"NONE, confd);


    struct my_file file;
    int size = sizeof(file);
    while(1){
        if(recv_packet(confd, (char*)&file, size) != -1){
            extract_data((char*)&file);
        }
        else{
            break;
        }
    }
    return 0;
}
